package com.lzy.stock_ranking_system.utils;

import com.lzy.stock_ranking_system.Bean.*;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.util.EntityUtils;
import org.springframework.stereotype.Component;

import java.io.*;
import java.net.URL;
import java.net.URLConnection;
import java.util.*;

import com.lzy.stock_ranking_system.Bean.zcfzbBean;

@Component
public class WebPageDownloader {

    private String url_zcfzb_dates = "https://emweb.securities.eastmoney.com/PC_HSF10/NewFinanceAnalysis/zcfzbDateAjaxNew?companyType=";
    //    +4+"&reportDateType=1&code=SH603369"
    private String url_zcfzb = "https://emweb.securities.eastmoney.com/PC_HSF10/NewFinanceAnalysis/zcfzbAjaxNew?companyType=";
//    "4&reportDateType=1&reportType=1&dates=2021-12-31,2020-12-31,2019-12-31,2018-12-31,2017-12-31&code=SH603369"
    private String url_lrb_dates = "https://emweb.securities.eastmoney.com/PC_HSF10/NewFinanceAnalysis/lrbDateAjaxNew?companyType=4&reportDateType=1" +
            "&code=";
    private String url_lrb = "https://emweb.securities.eastmoney.com/PC_HSF10/NewFinanceAnalysis/lrbAjaxNew?companyType=4&reportDateType=1&reportType=1&dates=";
//    +"2021-12-31,2020-12-31,2019-12-31,2018-12-31,2017-12-31&code=SH603369";
    private String url_xjllb_dates = "https://emweb.securities.eastmoney.com/PC_HSF10/NewFinanceAnalysis/xjllbDateAjaxNew?companyType=4&reportDateType=1" +
            "&code=";
    private String url_xjllb = "https://emweb.securities.eastmoney.com/PC_HSF10/NewFinanceAnalysis/xjllbAjaxNew?companyType=4&reportDateType=1&reportType=1&dates=";
//    +"2021-12-31,2020-12-31,2019-12-31,2018-12-31,2017-12-31&code=SH603369";
    private static final int MAX_TOTAL_CONNECTIONS = 100;
    private static final int MAX_PER_ROUTE_CONNECTIONS = 10;
    private final HttpClient httpClient;
    public WebPageDownloader() {
        PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager();
        connectionManager.setMaxTotal(MAX_TOTAL_CONNECTIONS);
        connectionManager.setDefaultMaxPerRoute(MAX_PER_ROUTE_CONNECTIONS);

        httpClient = HttpClientBuilder.create()
                .setConnectionManager(connectionManager)
                .build();
    }

    //获取资产负债表
    public void get_zcfzb(String code) {
        ArrayList<String> Dates = get_zcfzb_dates(code);
        if (Dates==null){
            return;
        }
        String url = null;
        String jsonPage = null;
        try {
            url=url_zcfzb+"4&reportDateType=1&reportType=1&dates=";
            for (int j = 0; j < Dates.size() - 1; j++) {
                url += Dates.get(j) + ",";
            }
            url += Dates.get(Dates.size() - 1) + "&code=" + code;
            jsonPage = getJsonPage_test(url);
            //jsonPage.length() == 152是指遇到证券银行股产生的报错信息的长度，直接略过这些股票
            if (jsonPage.length()==152){
                return;
            }
            if (jsonPage.length()<152){
                System.out.println(jsonPage);
                System.out.println(code);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        String dataString = JSONObject.fromObject(jsonPage).getString("data");
        JSONArray jsonArray = JSONArray.fromObject(dataString);

        ArrayList<zcfzbBean> arrayList = new ArrayList<>();
        zcfzbBean zcfzbbean;
        for (int i = 0; i < jsonArray.size(); i++) {
            zcfzbbean = new zcfzbBean();
            JSONObject jsonObject = jsonArray.getJSONObject(i);
            zcfzbbean.setSECURITY_CODE(jsonObject.getString("SECURITY_CODE"));
            zcfzbbean.setREPORT_DATE(jsonObject.getString("REPORT_DATE"));
            zcfzbbean.setTOTAL_EQUITY(Double.parseDouble(jsonObject.getString("TOTAL_EQUITY")));
            zcfzbbean.setTOTAL_ASSETS(Double.parseDouble(jsonObject.getString("TOTAL_ASSETS")));
            zcfzbbean.setMONETARYFUNDS(Double.parseDouble(jsonObject.getString("MONETARYFUNDS")));
            arrayList.add(zcfzbbean);
        }
        Map<String, ArrayList<zcfzbBean>> map = BeanList.getZcfzbBeanMap();
        if (arrayList.size()==0){
            System.out.println(url);
        }
        map.put(code + "", arrayList);
        BeanList.setZcfzbBeanMap(map);
    }

    public ArrayList<String> get_zcfzb_dates(String code) {
        ArrayList<String> Dates = new ArrayList<>();
        String url;
        String jsonPage=null;

        url=url_zcfzb_dates + "4&reportDateType=1&code=" + code;
        try {
            jsonPage = getJsonPage_test(url);
        } catch (IOException e) {
            e.printStackTrace();
        }
        //jsonPage.length() == 152是指遇到证券银行股产生的报错信息的长度，直接略过这些股票
        if (jsonPage.length() == 152) {
            return null;
        }
        if (jsonPage.length()<152){
            System.out.println(jsonPage);
            System.out.println(code);
        }
        JSONObject object = JSONObject.fromObject(jsonPage);
        String datesString = object.getString("data");
        JSONArray jsonArray = JSONArray.fromObject(datesString);

        for (int i = 0; i < jsonArray.size(); i++) {
            Dates.add(jsonArray.getJSONObject(i).getString("REPORT_DATE").substring(0, 10));
        }
        if (Dates.isEmpty()){
            System.out.println(url);
        }
        return Dates;
    }

    //获取利润表
    public void get_lrb(String code) {
        ArrayList<String> Dates = get_zcfzb_dates(code);
        if (Dates==null){
            return;
        }
        String url = null;
        String jsonPage = null;
        try {
            url=url_lrb;
            for (int j = 0; j < Dates.size() - 1; j++) {
                url += Dates.get(j) + ",";
            }
            url += Dates.get(Dates.size() - 1) + "&code=" + code;
            jsonPage = getJsonPage_test(url);
            //jsonPage.length() == 152是指遇到证券银行股产生的报错信息的长度，直接略过这些股票
            if (jsonPage.length()==152){
                return;
            }
            if (jsonPage.length()<152){
                System.out.println(jsonPage);
                System.out.println(code);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        String dataString = JSONObject.fromObject(jsonPage).getString("data");
//        System.out.println(dataString);//test
        JSONArray jsonArray = JSONArray.fromObject(dataString);

        ArrayList<lrbBean> arrayList = new ArrayList<>();
        lrbBean lrbbean;
        for (int i = 0; i < jsonArray.size(); i++) {
            lrbbean = new lrbBean();
            JSONObject jsonObject = jsonArray.getJSONObject(i);
            lrbbean.setSECURITY_CODE(jsonObject.getString("SECURITY_CODE"));
            lrbbean.setREPORT_DATE(jsonObject.getString("REPORT_DATE"));
            lrbbean.setPARENT_NETPROFIT(Double.parseDouble(jsonObject.getString("PARENT_NETPROFIT")));
            lrbbean.setNETPROFIT(Double.parseDouble(jsonObject.getString("NETPROFIT")));
            if (jsonObject.getString("TOTAL_OPERATE_INCOME")!="null") {
                lrbbean.setTOTAL_OPERATE_INCOME(Double.parseDouble(jsonObject.getString("TOTAL_OPERATE_INCOME")));
            }else{
                lrbbean.setTOTAL_OPERATE_INCOME(-1);
            }
            lrbbean.setTOTAL_OPERATE_COST(Double.parseDouble(jsonObject.getString("TOTAL_OPERATE_COST")));
            if(jsonObject.getString("INVEST_INCOME")!="null"){
                lrbbean.setINVEST_INCOME(Double.parseDouble(jsonObject.getString("INVEST_INCOME")));
            }else {
                lrbbean.setINVEST_INCOME(-1);
            }
            arrayList.add(lrbbean);
        }
        //将获取到的利润表数据添加到BeanList中
        Map<String, ArrayList<lrbBean>> map = BeanList.getLrbBeanMap();
        if (arrayList.size()==0){
            System.out.println(url);
        }
        map.put(code + "", arrayList);
        BeanList.setLrbBeanMap(map);
    }

    public ArrayList<String> get_lrb_dates(String code) {
        ArrayList<String> Dates = new ArrayList<>();
        String url;
        String jsonPage=null;

        url=url_lrb_dates + code;
        try {
            jsonPage = getJsonPage_test(url);
        } catch (IOException e) {
            e.printStackTrace();
        }
        //jsonPage.length() == 152是指遇到证券银行股产生的报错信息的长度，直接略过这些股票
        if (jsonPage.length() == 152) {
            return null;
        }
        if (jsonPage.length()<152){
            System.out.println(jsonPage);
            System.out.println(code);
        }
        JSONObject object = JSONObject.fromObject(jsonPage);
        String datesString = object.getString("data");
        JSONArray jsonArray = JSONArray.fromObject(datesString);

        for (int i = 0; i < jsonArray.size(); i++) {
            Dates.add(jsonArray.getJSONObject(i).getString("REPORT_DATE").substring(0, 10));
        }
        if (Dates.isEmpty()){
            System.out.println(url);
        }
        return Dates;
    }

    //获取现金流量表
    public void get_xjllb(String code) {
        ArrayList<String> Dates = get_xjllb_dates(code);
        if (Dates==null){
            return;
        }
        String url = null;
        String jsonPage = null;
        try {
            url=url_xjllb;
            for (int j = 0; j < Dates.size() - 1; j++) {
                url += Dates.get(j) + ",";
            }
            url += Dates.get(Dates.size() - 1) + "&code=" + code;
            jsonPage = getJsonPage_test(url);
            //jsonPage.length() == 152是指遇到证券银行股产生的报错信息的长度，直接略过这些股票
            if (jsonPage.length()==152){
                return;
            }
            if (jsonPage.length()<152){
                System.out.println(jsonPage);
                System.out.println(code);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        String dataString = JSONObject.fromObject(jsonPage).getString("data");
//        System.out.println(dataString);//test
        JSONArray jsonArray = JSONArray.fromObject(dataString);

        ArrayList<xjllbBean> arrayList = new ArrayList<>();
        xjllbBean xjllbbean;
        for (int i = 0; i < jsonArray.size(); i++) {
            xjllbbean = new xjllbBean();
            JSONObject jsonObject = jsonArray.getJSONObject(i);
            xjllbbean.setSECURITY_CODE(jsonObject.getString("SECURITY_CODE"));
            xjllbbean.setREPORT_DATE(jsonObject.getString("REPORT_DATE"));
            xjllbbean.setNETCASH_OPERATE((long) Double.parseDouble(jsonObject.getString("NETCASH_OPERATE")));
            arrayList.add(xjllbbean);
        }
        //将获取到的利润表数据添加到BeanList中
        Map<String, ArrayList<xjllbBean>> map = BeanList.getXjllbBeanMap();
        if (arrayList.size()==0){
            System.out.println(url);
        }
        map.put(code + "", arrayList);
        BeanList.setXjllbBeanMap(map);
    }

    public ArrayList<String> get_xjllb_dates(String code) {
        ArrayList<String> Dates = new ArrayList<>();
        String url;
        String jsonPage=null;

        url=url_xjllb_dates + code;
        try {
            jsonPage = getJsonPage_test(url);
        } catch (IOException e) {
            e.printStackTrace();
        }
        //jsonPage.length() == 152是指遇到证券银行股产生的报错信息的长度，直接略过这些股票
        if (jsonPage.length() == 152) {
            return null;
        }
        if (jsonPage.length()<152){
            System.out.println(jsonPage);
            System.out.println(code);
        }
        JSONObject object = JSONObject.fromObject(jsonPage);
        String datesString = object.getString("data");
        JSONArray jsonArray = JSONArray.fromObject(datesString);

        for (int i = 0; i < jsonArray.size(); i++) {
            Dates.add(jsonArray.getJSONObject(i).getString("REPORT_DATE").substring(0, 10));
        }
        if (Dates.isEmpty()){
            System.out.println(url);
        }
        return Dates;
    }

    public String getJsonPage_test(String url) throws IOException {
        HttpGet request = new HttpGet(url);

        try (CloseableHttpResponse response = (CloseableHttpResponse) httpClient.execute(request)) {
            return EntityUtils.toString(response.getEntity());
        }
    }

    public String getJsonPage(String url) {
        String response = new String();
        try {
            URLConnection connection = new URL(url).openConnection();
            Scanner scanner = new Scanner(connection.getInputStream(), "UTF-8");
            response = scanner.useDelimiter("\\A").next();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return response;
    }
}